home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / get2pcx.zip / GET2PCX.BAS next >
BASIC Source File  |  1997-05-23  |  16KB  |  508 lines

  1. '
  2. '  This program inputs image data from a Basic BSAVEd file and converts it
  3. ' to a PCX format.  The input and output files are specified on the
  4. ' command-line.  The Basic image must be in the format corresponding to
  5. ' the process of using the Basic GET command to transfer pixel data on the
  6. ' screen to an array and then BSAVEing the array.  (This program will NOT
  7. ' work with images BSAVEd directly from the video buffer.)  If the input
  8. ' file (first parameter on command-line) does not include an extension,
  9. ' ".GET" will be assumed.  Whatever you specify for the extension of the
  10. ' PCX output file (second parameter), it will be set to ".PCX" by the
  11. ' program.  If you don't specify a second parameter, your PCX file will
  12. ' have the same name as your "GET file" except for the extension.  (It
  13. ' might be a good idea if you didn't use an extension of ".PCX" on your
  14. ' GET file if you aren't going to specify a different second parameter!)
  15. '
  16. '  Upon running the program, it prompts you for the QB video mode that you
  17. ' used to make the Basic picture.  (Modes 1, 2, and 10 aren't supported,
  18. ' but you may be able to get away with specifying mode 11 if you're trying
  19. ' to convert mode 2 pictures.  Also, the program will now also convert
  20. ' SVGA Basic pictures to PCX.  If, however you generated them, you have
  21. ' 256-color SVGA pictures, specify mode 13 at the prompt for the video
  22. ' mode.  If you have SVGA pictures with 16 or less colors, specify any of
  23. ' the *other* allowed video modes.)  Finally, if you specify mode 9, it is
  24. ' assumed that you have *more* than 64K of EGA memory.  (Otherwise, mode 9
  25. ' isn't a 16-color mode, it's a 4-color mode, which, like mode 1, isn't
  26. ' supported.)
  27. '
  28. '  If, before running this program, you SET the DOS environment variable
  29. ' INVERSE to "ON", the PCX file will be generated in inverse video.  If
  30. ' your PCX image doesn't look at all right or your PCX viewer just can't
  31. ' interpret the file, try rerunning the program but SETting the DOS
  32. ' environment variable PCX to "SCAN" first.  (I think, however, that more
  33. ' often than not, if your PCX file isn't right, it's because you *did*
  34. ' SET PCX to "SCAN".)
  35. '
  36. '  Okay, for one more environment variable that you can SET before running
  37. ' the program, if you SET PALETTE to the name of a file, the 16 or 256-
  38. ' color RGB palette data will be input from that file instead of from the
  39. ' VGA's palette registers.  (The palette registers will still be used if
  40. ' the palette file contains insufficient information.)  The format of this
  41. ' file is simply 16 or 256 lines (depending on whether it's mode 12 or
  42. ' mode 13-compatible data) of RGB data, with a space between the RGB data
  43. ' on each line.  (The attributes are implied by the position of each line
  44. ' in the file.)
  45. '
  46. '  Process command-line.
  47. '
  48. CALL PARSE(COMMAND$," ",S1$,S2$)
  49. CALL PARSE(S1$,".",GETFILE$,EXT$)
  50. GETFILE$=RTRIM$(GETFILE$)
  51. EXT$=LTRIM$(EXT$)
  52. IF EXT$="" THEN EXT$="GET"
  53. S2$=LTRIM$(S2$)
  54. IF S2$="" THEN S2$=GETFILE$+".PCX"
  55. GETFILE$=GETFILE$+"."+EXT$
  56. CALL PARSE(S2$,".",PCXFILE$,EXT$)
  57. PCXFILE$=RTRIM$(PCXFILE$)
  58. PCXFILE$=PCXFILE$+".PCX"
  59. ON ERROR GOTO NOFILE
  60. OPEN GETFILE$ FOR INPUT AS #1
  61. CLOSE #1
  62. ON ERROR GOTO 0
  63. '
  64. '  Make various initializations.
  65. '
  66. DIM MODE AS INTEGER,BITS AS INTEGER,PLANES AS INTEGER,S AS STRING*1
  67. DIM BYTES AS LONG,HRES AS INTEGER,VRES AS INTEGER,W AS INTEGER,H AS INTEGER
  68. DIM COUNT AS LONG,RED AS INTEGER,BLUE AS INTEGER,GREEN AS INTEGER,I AS INTEGER
  69. DIM BPROW AS INTEGER,J AS INTEGER,SLAST AS STRING*1,BYTE AS INTEGER
  70. DIM CODEBYTE AS STRING*1,L AS INTEGER,LMAX AS INTEGER,BCOUNT AS LONG
  71. DIM IPAL AS INTEGER
  72. '
  73. '  Input video mode used to generate GET file.
  74. '
  75. MODE=0
  76. WHILE MODE<3 OR MODE>13 OR (MODE>4 AND MODE<7) OR MODE=10
  77. INPUT "What QB mode was used to make the GET file (3, 4, 7 - 9, 11, 12, or 13)";MODE
  78. WEND
  79. '
  80. '  Get header data from GET file and make sure it *is* a GET file.
  81. '
  82. OPEN GETFILE$ FOR BINARY AS #1
  83. GET#1,,S
  84. IF ASC(S)<>&HFD THEN GOTO NOTGETFILE
  85. '
  86. '  Make various initializations for creation of PCX header.
  87. '
  88. IF MODE=13 THEN HRES=320 : VRES=200 : PLANES=1 : BITS=8
  89. IF MODE=12 OR MODE=11 THEN HRES=640 : VRES=480 : PLANES=4 : BITS=4
  90. IF MODE=3 THEN HRES=720 : VRES=348 : PLANES=1 : BITS=1
  91. IF MODE=4  THEN HRES=640 : VRES=400 : PLANES=1 : BITS=1
  92. IF MODE=7 THEN HRES=320 : VRES=200 : PLANES=4 : BITS=4
  93. IF MODE=8 THEN HRES=640 : VRES=200 : PLANES=4 : BITS=4
  94. IF MODE=9 THEN HRES=640 : VRES=350 : PLANES=4 : BITS=4
  95. IF MODE=11 THEN PLANES=1 : BITS=1
  96. GET #1,,X
  97. GET#1,,S
  98. GET#1,,S
  99. GET#1,,W
  100. GET#1,,H
  101. BPROW=INT(CSNG(W+7)/8+.001)
  102. IF MODE=13 THEN W=W/8
  103. '
  104. '  Now that HRES and VRES have been defined, redefine them if SVGA video
  105. ' mode would be needed to display PCX image.
  106. '
  107. IF MODE=13 AND (W>320 OR H>200) THEN HRES=640 : VRES=480
  108. IF W>640 OR H>480 THEN HRES=800 : VRES=600
  109. IF W>800 OR V>600 THEN HRES=1024 : VRES=768
  110. IF W>1024 OR V>768 THEN HRES=1280 : VRES=1024
  111. IF W>1280 OR V>1024 THEN HRES=1600 : VRES=1200
  112. IF W>1600 OR H>1200 THEN GOTO NOTGETFILE
  113. '
  114. '  Okay, now that an SVGA mode might be implied, make sure MODE isn't 12.
  115. ' (16-color SVGA modes don't use the 256K RGB palette.  Hence, in this
  116. ' situation, there is no reason to put the screen in mode 12 or worry
  117. ' further about the palette.)
  118. '
  119. IF MODE=12 AND (W>640 OR H>480) THEN
  120. '
  121. '  (Actually, I could just set MODE to anything but 12 or 13 here.  I'm
  122. ' just being nitpicky for logic's sake.)
  123. '
  124. IF BITS=1 THEN MODE=11
  125. IF BITS=4 THEN MODE=9
  126. END IF
  127. '
  128. '  For standard QB modes, number of bytes in image could have been
  129. ' determined from last two S characters input above.  However, that method
  130. ' might not give the right value for an "SVGA GET file."  Hence, use LOF
  131. ' function.
  132. '
  133. BYTES=LOF(1)-11&
  134. IF CLNG(H)*CLNG(PLANES)*CLNG(BPROW)<>BYTES THEN GOTO NOTGETFILE
  135. W=W-1 : H=H-1
  136. '
  137. '  For modes that support the 256K palette, screen may need to be in
  138. ' actual video mode used to generate GET file in order to read palette
  139. ' data.
  140. '
  141. IF MODE>11 THEN
  142. ON ERROR GOTO NOSCREEN
  143. SCREEN MODE
  144. ON ERROR GOTO 0
  145. END IF
  146. '
  147. '  Delete old PCX file of same name as that being created.
  148. '
  149. ON ERROR GOTO NOPCX
  150. OPEN PCXFILE$ FOR INPUT AS #2
  151. CLOSE #2
  152. KILL PCXFILE$
  153. GOTO FILEDELETED
  154. NOPCX:
  155. RESUME FILEDELETED
  156. FILEDELETED:
  157. ON ERROR GOTO 0
  158. '
  159. '  Open PCX file and output header.
  160. '
  161. OPEN PCXFILE$ FOR BINARY AS #2
  162. S=CHR$(10)
  163. PUT#2,,S
  164. S=CHR$(5)
  165. PUT#2,,S
  166. S=CHR$(1)
  167. PUT#2,,S
  168. S=CHR$(INT(CSNG(BITS)/PLANES+.001))
  169. PUT#2,,S
  170. S=CHR$(0)
  171. FOR I=1 TO 4
  172. PUT#2,,S
  173. NEXT I
  174. PUT#2,,W
  175. PUT#2,,H
  176. PUT#2,,HRES
  177. PUT#2,,VRES
  178. '
  179. '  Define 16-color palette for modes 12 and 13.  (Well, to be honest, the
  180. ' palette is defined for lower modes too--the data is just set to zero.)
  181. ' If PALETTE environment variable is set to name of file storing palette
  182. ' data, that is where palette data is obtained from.  Otherwise, palette
  183. ' data is read from palette registers.
  184. '
  185. IPAL=0
  186. IF MODE>11 THEN
  187. ON ERROR GOTO NOPALFILE
  188. OPEN ENVIRON$("PALETTE") FOR INPUT AS #3
  189. IPAL=1
  190. GOTO GOTPALFILE
  191. NOPALFILE:
  192. RESUME GOTPALFILE
  193. GOTPALFILE:
  194. ON ERROR GOTO 0
  195. END IF
  196. RED=0 : GREEN=0 : BLUE=0
  197. FOR I=0 TO 15
  198. IF MODE>11 THEN
  199. IF IPAL=0 THEN GOTO READREG
  200. IF IPAL=1 THEN IF EOF(3) THEN GOTO READREG
  201. IF IPAL=1 THEN INPUT#3,RED,GREEN,BLUE
  202. GOTO GOTRGB
  203. READREG:
  204. CALL PALREAD(I,RED,GREEN,BLUE)
  205. GOTRGB:
  206. END IF
  207. S=CHR$(RED)
  208. PUT#2,,S
  209. S=CHR$(GREEN)
  210. PUT#2,,S
  211. S=CHR$(BLUE)
  212. PUT#2,,S
  213. NEXT I
  214. IF IPAL=1 THEN CLOSE #3
  215. '
  216. '  Hercules and ATT/Olivetti modes are aliased in the PCX file as mode 11.
  217. ' (This isn't really important because this byte isn't used for anything;
  218. ' most PCX files just have a 0 for this byte.)
  219. '
  220. IF MODE=3 OR MODE=4 THEN S=CHR$(&H11)
  221. '
  222. '  Use bios modes, not QB mode integers.  (It works out that for QB modes
  223. ' 11 and above the QB mode integer is the same as the hexadecimal bios
  224. ' mode integer.)
  225. '
  226. IF MODE=7 THEN S=CHR$(&HD)
  227. IF MODE=8 THEN S=CHR$(&HE)
  228. IF MODE=9 THEN S=CHR$(&H10)
  229. IF MODE>=11 THEN S=CHR$(VAL("&H"+LTRIM$(RTRIM$(STR$(MODE)))))
  230. PUT#2,,S
  231. S=CHR$(PLANES)
  232. PUT#2,,S
  233. PUT#2,,BPROW
  234. S=CHR$(1)
  235. PUT#2,,S
  236. S=CHR$(0)
  237. FOR I=1 TO 59
  238. PUT#2,,S
  239. NEXT I
  240. '
  241. '  PCX header is generated.  Transfer graphics data to PCX file.
  242. '
  243. '  Get INVERSE and PCX environment variables.
  244. '
  245. INVERSE$=UCASE$(LTRIM$(RTRIM$(ENVIRON$("INVERSE"))))
  246. PCX$=UCASE$(LTRIM$(RTRIM$(ENVIRON$("PCX"))))
  247. '
  248. '  Graphics data is transferred one scan line at a time if PCX$ = "SCAN".
  249. '
  250. LMAX=H : BCOUNT=CLNG(BPROW*PLANES)
  251. IF PCX$<>"SCAN" THEN LMAX=0 : BCOUNT=BYTES
  252. FOR L=0 TO LMAX
  253. '
  254. '  Input "starter byte."
  255. '
  256. GET#1,,SLAST
  257. COUNT=1&
  258. GETBYTE:
  259. '
  260. '  J stores the number of identical bytes to be repeated when PCX file is
  261. ' read by PCX viewer.
  262. '
  263. J=1
  264. IF COUNT<BCOUNT THEN
  265. '
  266. '  Look for up to 63 identical graphics bytes and store them as two bytes,
  267. ' one giving a counter and the second giving the byte to be repeated.
  268. '
  269. FOR I=2 TO 63
  270. GET#1,,S
  271. COUNT=COUNT+1&
  272. IF S=SLAST THEN J=I
  273. IF S<>SLAST THEN EXIT FOR
  274. IF COUNT=BCOUNT THEN EXIT FOR
  275. NEXT I
  276. END IF
  277. '
  278. '  CODEBYTE may store the above mentioned counter, or it may not be used
  279. ' at all.
  280. '
  281. CODEBYTE=CHR$(192+J)
  282. BYTE=ASC(SLAST)
  283. IF INVERSE$="ON" THEN
  284. '
  285. '  Reverse bits.  (BYTE needs to be regenerated in this case so it can be
  286. ' used properly below.)
  287. '
  288. SLAST=CHR$(&HFF AND (NOT BYTE))
  289. BYTE=ASC(SLAST)
  290. END IF
  291. '
  292. '  If there's only one identical image byte in the sequence, the code
  293. ' byte isn't needed unless the byte > 191.
  294. '
  295. IF BYTE>191 OR J>1 THEN PUT#2,,CODEBYTE
  296. PUT#2,,SLAST
  297. IF COUNT<BCOUNT THEN
  298. '
  299. '  If all 63 bytes input above are identical, a new starter byte is
  300. ' needed.
  301. '
  302. IF J=63 THEN
  303. GET#1,,SLAST
  304. COUNT=COUNT+1&
  305. END IF
  306. '
  307. '  If all (less than 63) bytes input above aren't identical, starter byte
  308. ' is already available--it's the last byte input from the GET file.
  309. '
  310. IF J<63 THEN SLAST=S
  311. GOTO GETBYTE
  312. END IF
  313. NEXT L
  314. '
  315. '  Image data is transferred; CLOSE GET file.
  316. '
  317. CLOSE #1
  318. IF BITS=8 THEN
  319. '
  320. '  Process 256-color palette.  (Again, get data from file if PALETTE
  321. ' environment variable exists.)
  322. '
  323. IF IPAL=1 THEN OPEN ENVIRON$("PALETTE") FOR INPUT AS #1
  324. S=CHR$(12)
  325. PUT#2,,S
  326. FOR I=0 TO 255
  327. IF IPAL=0 THEN GOTO READREG1
  328. IF IPAL=1 THEN IF EOF(1) THEN GOTO READREG1
  329. IF IPAL=1 THEN INPUT#1,RED,GREEN,BLUE
  330. GOTO GOTRGB1
  331. READREG1:
  332. CALL PALREAD(I,RED,GREEN,BLUE)
  333. GOTRGB1:
  334. S=CHR$(RED)
  335. PUT#2,,S
  336. S=CHR$(GREEN)
  337. PUT#2,,S
  338. S=CHR$(BLUE)
  339. PUT#2,,S
  340. NEXT I
  341. IF IPAL=1 THEN CLOSE #1
  342. END IF
  343. '
  344. '  PCX file is generated; CLOSE it and quit.
  345. '
  346. CLOSE #2
  347. IF MODE>11 THEN SCREEN 0
  348. GOTO QUITPROG
  349. NOFILE:
  350. '
  351. '  Input file wasn't specified.
  352. '
  353. PRINT
  354. PRINT "Syntax:"
  355. PRINT
  356. PRINT "GET2PCX get_file pcx_file"
  357. PRINT
  358. PRINT "  (get_file has default .GET extension.  pcx_file will have .PCX extens";
  359. PRINT "sion and"
  360. PRINT "will have otherwise same name as get_file if you don't specify it.)"
  361. PRINT
  362. GOTO QUITPROG
  363. NOSCREEN:
  364. CLOSE #1
  365. '
  366. '  You don't have support for the video mode that generated the Basic
  367. ' image.
  368. '
  369. PRINT
  370. PRINT "You don't have support for screen mode ";LTRIM$(RTRIM$(STR$(MODE)));"."
  371. GOTO QUITPROG
  372. NOTGETFILE:
  373. CLOSE #1
  374. '
  375. '  You didn't specify a valid GET file.
  376. '
  377. PRINT
  378. PRINT "  ";GETFILE$;" doesn't appear to be a standard QB 'GET file.'  "
  379. PRINT "(Perhaps you specified a wrong video"
  380. PRINT "mode.)"
  381. QUITPROG:
  382. END
  383. '
  384. '  This subroutine parses as string S$ into the two strings S1$ and S2$
  385. ' based on the delimiter DL$.
  386. '
  387. SUB PARSE(S$,DL$,S1$,S2$)
  388. SI$=LTRIM$(RTRIM$(S$))
  389. N=LEN(SI$)
  390. S1$=SI$
  391. S2$=""
  392. IF N=0 THEN GOTO TERM
  393. I=INSTR(SI$,DL$)
  394. IF I=0 THEN GOTO TERM
  395. S1$=MID$(SI$,1,I-1)
  396. S2$=MID$(SI$,I+LEN(DL$),N-I-LEN(DL$)+1)
  397. TERM:
  398. END SUB
  399. '
  400. '  This subroutine inputs attribute ATTRIB and returns the RED, GREEN,
  401. ' and BLUE color values that are currently assigned to ATTRIB via the
  402. ' color palette.  At least, that's what it does for QB modes 11 and above
  403. ' since they support the 256K-color RGB palette.  The RGB data can be
  404. ' converted to the actual assigned color via
  405. '
  406. '  PALCOL = RED + 256& * GREEN + 65536& * BLUE.
  407. '
  408. '  For lesser screen modes, the palette color itself is returned via the
  409. ' RED parameter.  All parameters passed to/from the routine are of INTEGER
  410. ' type.
  411. '
  412. '  Do not input a value for ATTRIB larger than allowed by the video mode
  413. ' (which you must set *before* calling this routine).  For SCREEN 11 and
  414. ' other monochrome modes, 0 <= ATTRIB <= 1.  For SCREEN 1 and 10, 0 <=
  415. ' ATTRIB <= 3.  For SCREEN 7 - 9 and 12, 0 <= ATTRIB <= 15.  For SCREEN 13,
  416. ' ATTRIB can be as large as 255.
  417. '
  418. '  The subroutine uses various functions and subfunctions of interrupt 10.
  419. ' (Do not get the erroneous idea that I am a machine code/ASM hotshot!
  420. ' Although the code works, I'm sure that any number of such true hotshots
  421. ' can/will tear this code to pieces!  <g>)
  422. '
  423. SUB PALREAD(ATTRIB AS INTEGER,RED AS INTEGER,GREEN AS INTEGER,BLUE AS INTEGER)
  424. DIM MCODE(1 TO 14) AS LONG,CX AS INTEGER,DX AS INTEGER,OS AS INTEGER
  425. DIM BX AS INTEGER,AX AS INTEGER,MODE AS INTEGER
  426. '
  427. '  Set up machine code routines.
  428. '
  429. DEF SEG=VARSEG(MCODE(1))
  430. '
  431. '  FOR READING 256K-COLOR/RGB PALETTE
  432. '
  433. OS=VARPTR(MCODE(1))
  434. POKE OS,&HB8 : POKE OS+1,&H15 : POKE OS+2,&H10        'MOV AX,1015
  435. POKE OS+3,&HBB : POKE OS+4,ATTRIB : POKE OS+5,0       'MOV BX,[ATTRIB]
  436. POKE OS+6,&H55                                        'PUSH BP
  437. POKE OS+7,&H89 : POKE OS+8,&HE5                       'MOV BP,SP
  438. POKE OS+9,&HCD : POKE OS+10,&H10                      'INT 10
  439. POKE OS+11,&H8B : POKE OS+12,&H5E : POKE OS+13,6      'MOV BX,[BP+6]
  440. POKE OS+14,&H89 : POKE OS+15,&H17                     'MOV [BX],DX
  441. POKE OS+16,&H8B : POKE OS+17,&H5E : POKE OS+18,8      'MOV BX,[BP+8]
  442. POKE OS+19,&H89 : POKE OS+20,&HF                      'MOV [BX],CX
  443. POKE OS+21,&H5D                                       'POP BP
  444. POKE OS+22,&HCB                                       'RETF
  445. '
  446. '  FOR READING 16-COLOR PALETTE
  447. '
  448. OS=OS+23
  449. POKE OS,&HB8 : POKE OS+1,7 : POKE OS+2,&H10           'MOV AX,1007
  450. POKE OS+3,&HBB : POKE OS+4,ATTRIB : POKE OS+5,0       'MOV BX,[ATTRIB]
  451. POKE OS+6,&H55                                        'PUSH BP
  452. POKE OS+7,&H89 : POKE OS+8,&HE5                       'MOV BP,SP
  453. POKE OS+9,&HCD : POKE OS+10,&H10                      'INT 10
  454. POKE OS+11,&H89 : POKE OS+12,&HD8                     'MOV AX,BX
  455. POKE OS+13,&H8B : POKE OS+14,&H5E : POKE OS+15,6      'MOV BX,[BP+6]
  456. POKE OS+16,&H89 : POKE OS+17,7                        'MOV [BX],AX
  457. POKE OS+18,&H5D                                       'POP BP
  458. POKE OS+19,&HCB                                       'RETF
  459. '
  460. '  FOR GETTING VIDEO MODE
  461. '
  462. OS=OS+20
  463. POKE OS,&HB8 : POKE OS+1,0 : POKE OS+2,&HF            'MOV AX,F00
  464. POKE OS+3,&H55                                        'PUSH BP
  465. POKE OS+4,&H89 : POKE OS+5,&HE5                       'MOV BP,SP
  466. POKE OS+6,&HCD : POKE OS+7,&H10                       'INT 10
  467. POKE OS+8,&H8B : POKE OS+9,&H5E : POKE OS+10,6        'MOV BX,[BP+6]
  468. POKE OS+11,&H89 : POKE OS+12,7                        'MOV [BX],AX
  469. POKE OS+13,&H5D                                       'POP BP
  470. POKE OS+14,&HCB                                       'RETF
  471. '
  472. '  First, get video mode.  (It determines how palette is interpreted.)
  473. '
  474. CALL ABSOLUTE(AX,OS)
  475. MODE=AX AND &HFF
  476. '
  477. '  Offset has to be set back by at least 20.
  478. '
  479. OS=OS-20
  480. IF MODE<&H11 THEN
  481. '
  482. '  16-COLOR (OR LESS) MODE
  483. '
  484. '  Just get color value.
  485. '
  486. CALL ABSOLUTE(BX,OS)
  487. '
  488. '  Palette color is in BH.  Return it as RED in parameter list.
  489. '
  490. RED=(BX AND &HFF00)/256
  491. ELSE
  492. '
  493. '  256-COLOR MODE
  494. '
  495. '  Get RGB data (after setting OS back to beginning of MCODE array).
  496. '
  497. OS=OS-23
  498. CALL ABSOLUTE(CX,DX,OS)
  499. '
  500. '  Red is in DH, green is in CH, and blue is in CL.
  501. '
  502. RED=(DX AND &HFF00)/256
  503. GREEN=(CX AND &HFF00)/256
  504. BLUE=CX AND &HFF
  505. END IF
  506. DEF SEG
  507. END SUB
  508.